package service

import (
	"context"
	"io/ioutil"
	"math"
	"mygf2/internal/model/entity"
	"net/http"
	"regexp"
	"strings"

	"github.com/gogf/gf/v2/encoding/gjson"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/text/gregex"
	"github.com/gogf/gf/v2/text/gstr"
	"github.com/gogf/gf/v2/util/gconv"
)

var (
	KuaishouService = kauishouService{}
)

type kauishouService struct{}

func (k *kauishouService) GetPrefixPattern() (res string) {
	res = `kuaishou\.com\/`
	return
}
func (k *kauishouService) MakeUrl(url string) (res string) {
	return
}
func (k *kauishouService) GetTags(title string) string {
	//解析出tags
	title = strings.Trim(title, "#")
	tagList := strings.Split(title, "#")
	//fmt.Println(tagList)
	tags := []string{}
	for i := 1; i < len(tagList); i++ {
		tags = append(tags, gstr.TrimAll(tagList[i], SpecialCharacterMask...))
	}
	return strings.Join(tags, ",")
}
func (k *kauishouService) FormatTitle(title string) string {
	//去掉@后的数据
	strList := strings.Split(title, "@")
	//fmt.Println(strList[0])
	//fmt.Println(strings.TrimSpace(strList[0]))
	return strings.TrimSpace(strList[0])
}

func (ks *kauishouService) Fetch(ctx context.Context, url string, taskChan chan interface{}) (res *entity.GatherUrls) {
	defer func() {
		taskChan <- res
	}()
	//判断匹配嘛
	url = ks.GetUrl(url)
	if url == "" {
		return
	}

	client := &http.Client{
		// return http.ErrUseLastResponse。
		// CheckRedirect: func(req *http.Request, via []*http.Request) error {
		// 	return http.ErrUseLastResponse
		// 	// return nil nil回重定向。
		// },
	}
	resp, err := client.Get(url)
	if err != nil {
		return
	}
	cookies := resp.Cookies()
	//fmt.Println(cookies)
	secondUrl := resp.Request.URL.String()
	//fmt.Println(secondUrl)
	photoIdPattern := `video/(.*)\?`
	photoIdreg := regexp.MustCompile(photoIdPattern)
	photoIdMatchs := photoIdreg.FindAllStringSubmatch(secondUrl, -1)
	photoId := "" //视频id
	if photoIdMatchs != nil && len(photoIdMatchs[0]) > 1 {
		photoId = photoIdMatchs[0][1]
	}

	var req *http.Request
	req, _ = http.NewRequest("GET", secondUrl, nil)
	//设置cookie
	for _, c := range cookies {
		req.AddCookie(c)
	}
	//设置header
	for k, v := range Kuaishouheaders {
		req.Header.Add(k, v)
	}
	resp, err = client.Do(req)
	if err != nil {
		g.Log().Debug(ctx, err)
		return
	}
	defer resp.Body.Close()
	b, _ := ioutil.ReadAll(resp.Body)
	html := string(b)
	//g.Log().Debug(ctx, html)
	//解析出地址
	matechs, err := gregex.MatchString(`<script type="text\/javascript">[\s]*window.pageData[\s]*\=[\s]*(.*?)<\/script>`, html)
	if len(matechs) < 2 || err != nil {
		g.Log().Error(ctx, "匹配出问题", matechs, err)
	}
	//g.Log().Debug(ctx, matechs[1], photoId)
	jsonInfo := gstr.Replace(matechs[1], "undefined", "null")
	j := gjson.New(jsonInfo)
	title := j.Get("video.caption").String()
	//photoId := j.Get("anyVideo.gidInformation.gid").String()
	media_type := j.Get("video.type").String()
	if media_type != "video" {
		g.Log().Error(ctx, media_type, "不是视频")
		return
	}
	queryData := new(entity.GatherUrls)
	queryData.Source = "kuaishou"
	queryData.Title = ks.FormatTitle(title)
	queryData.Url = "https://www.kuaishou.com/short-video/" + photoId
	queryData.OriginId = photoId
	queryData.Width = j.Get("rawPhoto.width").Int()
	queryData.Height = j.Get("rawPhoto.height").Int()
	//1080p
	nowatermarkUrl := j.Get("video.srcNoMark").String()

	queryData.NowatermarkUrl = nowatermarkUrl
	coverImg := j.Get("video.poster").String()
	queryData.Cover = coverImg
	duration := j.Get("rawPhoto.duration").Float64()
	queryData.Duration = gconv.Int(math.Ceil(duration / 1000.0))
	queryData.Tags = ks.GetTags(queryData.Title)
	//gutil.Dump(queryData)
	//下一步进行存储数据库吧
	res = GatherUrls().GatherInTable(ctx, queryData)
	return
}

func (ks *kauishouService) FetchBak(ctx context.Context, url string, taskChan chan interface{}) (res *entity.GatherUrls) {
	defer func() {
		taskChan <- res
	}()
	//判断匹配嘛
	url = ks.GetUrl(url)
	if url == "" {
		return
	}

	client := &http.Client{
		// return http.ErrUseLastResponse。
		// CheckRedirect: func(req *http.Request, via []*http.Request) error {
		// 	return http.ErrUseLastResponse
		// 	// return nil nil回重定向。
		// },
	}
	resp, err := client.Get(url)
	if err != nil {
		return
	}
	cookies := resp.Cookies()
	//fmt.Println(cookies)
	secondUrl := resp.Request.URL.String()
	//fmt.Println(secondUrl)
	photoIdPattern := `video/(.*)\?`
	photoIdreg := regexp.MustCompile(photoIdPattern)
	photoIdMatchs := photoIdreg.FindAllStringSubmatch(secondUrl, -1)
	photoId := "" //视频id
	if photoIdMatchs != nil && len(photoIdMatchs[0]) > 1 {
		photoId = photoIdMatchs[0][1]
	}

	var req *http.Request
	req, _ = http.NewRequest("GET", secondUrl, nil)
	//设置cookie
	for _, c := range cookies {
		req.AddCookie(c)
	}
	//设置header
	for k, v := range Kuaishouheaders {
		req.Header.Add(k, v)
	}
	resp, err = client.Do(req)
	if err != nil {
		g.Log().Debug(ctx, err)
		return
	}
	defer resp.Body.Close()
	b, _ := ioutil.ReadAll(resp.Body)
	html := string(b)
	//g.Log().Debug(ctx, html)
	//解析出地址
	urlPattern := `"srcNoMark":"(https://.*?\.mp4)`
	reg := regexp.MustCompile(urlPattern)
	matchs := reg.FindAllStringSubmatch(html, -1)
	//g.Log().Debug(ctx, matchs)
	if matchs == nil {
		return
	}
	//fmt.Println(matchs[0][1])
	//srcNoMark := matchs[0][1]
	//fmt.Println(srcNoMark)
	//解析出获取标题
	titlePattern := `"rawPhoto":[\s\S]*?"caption":\s*"([\s\S]*?)",`
	regTitle := regexp.MustCompile(titlePattern)
	matchTitles := regTitle.FindAllStringSubmatch(html, -1)
	//fmt.Println(matchTitles[0][1])
	if matchTitles == nil {
		g.Log().Debug(ctx, "没有匹配标题")
		return
	}
	//封面图
	coverPattern := `"poster":\s*"(https://.*?)"`
	coverReg := regexp.MustCompile(coverPattern)
	coverMatchs := coverReg.FindAllStringSubmatch(html, -1)

	//取得宽度与高度
	widthPattern := `"rawPhoto":[\s\S]*?"width":\s*?(\d*),`
	widthReg := regexp.MustCompile(widthPattern)
	widthMatchs := widthReg.FindAllStringSubmatch(html, -1)

	heightPattern := `"rawPhoto":[\s\S]*?"height":\s*?(\d*),`
	heightReg := regexp.MustCompile(heightPattern)
	heightMatchs := heightReg.FindAllStringSubmatch(html, -1)
	//height := heightMatchs[0][1]
	//取得时长
	durationPattern := `"rawPhoto":[\s\S]*?"duration":\s*?(\d*),`
	durationReg := regexp.MustCompile(durationPattern)
	durationMatchs := durationReg.FindAllStringSubmatch(html, -1)

	//fmt.Println(matchs[0][1])
	queryData := new(entity.GatherUrls)
	queryData.Source = "kuaishou"
	queryData.Title = ks.FormatTitle(matchTitles[0][1])
	queryData.Url = "https://www.kuaishou.com/short-video/" + photoId
	queryData.OriginId = photoId
	nowatermarkUrl := matchs[0][1]
	//替换成可访问的链接
	nowatermarkUrl, err = gregex.ReplaceString(`https:\/\/v\d*\.kwaicdn\.com`, "https://txmov2.a.kwimgs.com", nowatermarkUrl)
	if matchTitles == nil {
		g.Log().Debug(ctx, "无水印图替换失败了")
		return
	}
	queryData.NowatermarkUrl = nowatermarkUrl
	if coverMatchs != nil && len(coverMatchs[0]) > 1 {
		queryData.Cover = coverMatchs[0][1]
	}
	if widthMatchs != nil && len(widthMatchs[0]) > 1 {
		queryData.Width = gconv.Int(widthMatchs[0][1])
	}
	if heightMatchs != nil && len(heightMatchs[0]) > 1 {
		queryData.Height = gconv.Int(heightMatchs[0][1])
	}
	if durationMatchs != nil && len(durationMatchs[0]) > 1 {
		duration := gconv.Float64(durationMatchs[0][1])
		queryData.Duration = gconv.Int(math.Ceil(duration / 1000.0))
	}
	queryData.Tags = ks.GetTags(queryData.Title)
	//下一步进行存储数据库吧
	res = GatherUrls().GatherInTable(ctx, queryData)
	//fmt.Println(matchTitles[0][1])
	return
}

func (k *kauishouService) Download(ctx context.Context, url string) (res string, err error) {
	return
}
func (k *kauishouService) GetUrl(url string) (res string) {
	//快手有网页版分享链接，
	if find := strings.Contains(url, "kuaishouapp"); find {
		pattern := `v.kuaishouapp.com\/s\/\w+`
		reg := regexp.MustCompile(pattern)
		matchs := reg.FindAllString(url, -1)
		if matchs == nil {
			return ""
		}
		res = "https://v.kuaishouapp.com/s/" + strings.Replace(matchs[0], "v.kuaishouapp.com/s/", "", -1)
	} else if find := strings.Contains(url, "www.kuaishou"); find {
		pattern := `www.kuaishou.com\/[\w\/\-]+`
		reg := regexp.MustCompile(pattern)
		matchs := reg.FindAllString(url, -1)
		if matchs == nil {
			return ""
		}
		res = "https://www.kuaishou.com/" + strings.Replace(matchs[0], "www.kuaishou.com/", "", -1)
	} else {
		pattern := `v.kuaishou.com\/\w+`
		reg := regexp.MustCompile(pattern)
		matchs := reg.FindAllString(url, -1)
		if matchs == nil {
			return ""
		}
		res = "https://v.kuaishou.com/" + strings.Replace(matchs[0], "v.kuaishou.com/", "", -1)
	}
	return
}

//需要验证码，未找到好的方法
func (ks *kauishouService) GatherByAuthor(ctx context.Context, url string) (res []*entity.GatherUrls) {

	return
}
